package org.msb.accentis.gui.models;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.table.AbstractTableModel;

import org.msb.accentis.data.DataManagerFactory;
import org.msb.accentis.data.Database;
import org.msb.accentis.data.IDataManager;
import org.msb.accentis.data.IDataManagerFactoryListener;
import org.msb.accentis.data.IObjectListener;
import org.msb.accentis.data.pojo.Account;
import org.msb.accentis.data.pojo.Transaction;

@SuppressWarnings("serial")
public abstract class AbstractTransactionTableModel extends AbstractTableModel implements IDataManagerFactoryListener {

	protected List<Transaction> list = new ArrayList<Transaction>();
	
	protected Account account;
	
	private final Map<String, Object> queryParameters = new HashMap<String, Object>();
	
	protected IObjectListener transactionDataManagerListener;
	
	protected AbstractTransactionTableModel() {
		DataManagerFactory.getInstance().addDataManagerFactoryListener(this);
	}
	
	@Override
	public int getRowCount() {
		return list.size();
	}

	@Override
	public int getColumnCount() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void databaseChanged(Database database) {
		clear();
		
		if (null != database)
			database.getObjectNotifier().addListener(getTransactionDataManagerListener());
		
		load(database.getDataManager());
	}

	protected List<Transaction> getTransactions() {
		return list;
	}

	protected void addTransaction(Transaction transaction, int index) {
		list.add(index, transaction);
	}
	
	protected void removeTransaction(int index) {
		list.remove(index);
	}

	public Transaction getTransactionAt(int index) {
		return list.get(index);
	}
	
	public Account getAccount() {
		return account;
	}

	public void setAccount(Account value) {
		account = value;
		queryParameters.put("account", value); //$NON-NLS-1$
	
		reload();
	}

	protected void clear() {
		int size = getRowCount();
		list.clear();
		fireTableRowsDeleted(0, size);
	}

	public void reload() {
		clear();
		load(DataManagerFactory.getInstance().getDatabase().getDataManager());
	}

	
	private void load(IDataManager dataManager) {
		if (null != dataManager && null != account) {
			list.clear();
	
			List<Transaction> transactions = dataManager.<Transaction> runNamedQuery("Transaction.getTransactionDetailsForAccount", queryParameters); //$NON-NLS-1$
			for (int i = 0; i < transactions.size(); ++i) {
				Transaction transaction = transactions.get(i);
				addTransaction(transaction, i);
			}

			fireTableRowsInserted(0, getRowCount());
		}
	}
	
	protected IObjectListener getTransactionDataManagerListener() {
		if (null == transactionDataManagerListener)
			transactionDataManagerListener = createTransactionDataManagerListener();
		
		return transactionDataManagerListener;
	}
	
	protected abstract IObjectListener createTransactionDataManagerListener();
}
